﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DCT.Service.Restriction.Utility.Config;

namespace DCT.Service.Restriction.Utility.Log
{
    public class MultiLog : LogSkeleton
    {
        private List<ILog> logs = new List<ILog>();
        private Dictionary<string, IConfigParser> configs = new Dictionary<string, IConfigParser>();

        /*
         <root>
            <level></level> /总控制
            <list key="logs">
                <object>
                    <name>aaa</name>
                    <level>all</level>
                </object>
                <object>
                    <name>bbb</name>
                    <level>all</level>
                </object>
            </list>
         </root>
         */

        public override IConfigParser LoadConfig(IConfigParser config)
        {
            configs.Clear();
            var logs = config.GetListKV("logs");
            foreach (var item in logs)
            {
                Dictionary<string, string> kv = CollectionUtility.Convert(item);
                string name = "";
                if (kv.TryGetValue("name", out name))
                {
                    this.configs[name] = XmlConfigParser.Parse( kv);
                }
            }
            //最好调用，不然获取this.ConfigParser的时候会报错            
            return base.LoadConfig(config);
        }

        /// <summary>
        /// 如果需要加载配置，需要先执行LoadConfig，再执行SetMultiLogs
        /// </summary>
        /// <param name="settinglogs"></param>
        public void SetMultiLogs(Dictionary<string, ILog> settinglogs)
        {
            if (CollectionUtility.IsEmptyOrNull(this.configs))
            {
                throw new InvalidOperationException("请先执行LoadConfig加载有效配置");
            }
            this.logs.Clear();
            foreach (var item in settinglogs)
            {
                ILog tmpLog = item.Value;
                string name = item.Key;
                if (this.configs.ContainsKey(name))
                {
                    tmpLog.LoadConfig(this.configs[name]);
                }
                this.logs.Add(tmpLog);
            }
        }

        public override void D(string tag, string msg, Exception exception)
        {
            this.MultiWriteLog(LogLevel.Debug, tag, msg, exception);
        }

        public override void I(string tag, string msg, Exception exception)
        {
            this.MultiWriteLog(LogLevel.Info, tag, msg, exception);
        }

        public override void W(string tag, string msg, Exception exception)
        {
            this.MultiWriteLog(LogLevel.Warning, tag, msg, exception);
        }

        public override void E(string tag, string msg, Exception exception)
        {
            this.MultiWriteLog(LogLevel.Error, tag, msg, exception);
        }

        public override void F(string tag, string msg, Exception exception)
        {
            this.MultiWriteLog(LogLevel.Fatal, tag, msg, exception);
        }

        private void MultiWriteLog(LogLevel level, string tag, string msg, Exception exception)
        {
            if (this.EnabledLog(level))
            {
                //遍历
                foreach (var log in this.logs)
                {
                    if (log.EnabledLog(level))
                    {
                        log.Log(level, tag, msg, exception);
                    }
                }
            }
        }
    }
}
